package io.github.echarts.model.adapter.series;

import io.github.echarts.model.SeriesModel;
import io.github.echarts.model.context.ConfigurationContext;
import io.github.echarts.model.coordinate.CoordinateSystem;
import io.github.echarts.model.coordinate.DataRange;
import io.github.echarts.option.series.LineSeries;
import io.github.echarts.option.series.SeriesOption;

import java.util.Collections;
import java.util.List;

/**
 * 折线图系列适配器
 * <p>
 * 该适配器负责折线图系列的适配工作。
 * </p>
 */
public class LineSeriesAdapter extends AbstractSeriesTypeAdapter {
    
    /**
     * 构造函数
     */
    public LineSeriesAdapter() {
        super("line");
    }
    
    @Override
    public SeriesModel createModel(SeriesOption seriesOption, String coordinateSystemId, ConfigurationContext context) {
        if (!(seriesOption instanceof LineSeries)) {
            throw new IllegalArgumentException("SeriesOption must be a LineSeries");
        }
        
        final LineSeries lineSeries = (LineSeries) seriesOption;
        
        // 创建简单的SeriesModel实现，实现所有必需的抽象方法
        SeriesModel model = new SeriesModel() {
            private int seriesIndex = 0;
            private CoordinateSystem coordinateSystem = null;
            private DataRange dataRange = new DataRange(0, 100); // 默认范围
            
            @Override
            public String getType() {
                return "line";
            }
            
            @Override
            public String getName() {
                return lineSeries.getName();
            }
            
            @Override
            public String getCoordinateSystemId() {
                return coordinateSystemId;
            }
            
            @Override
            public int getSeriesIndex() {
                return seriesIndex;
            }
            
            @Override
            public void setSeriesIndex(int index) {
                this.seriesIndex = index;
            }
            
            @Override
            public List<Object> getData() {
                // 由于getData返回类型与setData参数类型不匹配，需要进行适当的转换
                // 这里返回一个空列表，实际项目中应根据具体需求实现
                return Collections.emptyList();
            }
            
            @Override
            public void processData() {
                // 处理数据，实际项目中应根据具体需求实现
            }
            
            @Override
            public DataRange getDataRange() {
                return dataRange;
            }
            
            @Override
            public double[] getDataRangeValues() {
                // 返回数据范围值
                return new double[] {dataRange.getMin(), dataRange.getMax()};
            }
            
            @Override
            public String getStack() {
                return lineSeries.getStack();
            }
            
            @Override
            public int getZLevel() {
                // 返回默认z-level
                return 0;
            }
            
            @Override
            public CoordinateSystem getCoordinateSystem() {
                return coordinateSystem;
            }
            
            @Override
            public void setCoordinateSystem(CoordinateSystem coordinateSystem) {
                this.coordinateSystem = coordinateSystem;
            }
        };
        
        // 根据数据特性进行优化配置
        optimizeLineSeriesConfig(model, lineSeries, context);
        
        return model;
    }
    
    @Override
    public void optimizeVisualStyle(SeriesModel seriesModel, ConfigurationContext context) {
        super.optimizeVisualStyle(seriesModel, context);
        
        // 检查数据密度，调整样式
        optimizeLineStyle(seriesModel, context);
    }
    
    /**
     * 优化折线图配置
     * 
     * @param model 系列模型
     * @param lineSeries 折线系列配置
     * @param context 配置上下文
     */
    private void optimizeLineSeriesConfig(SeriesModel model, LineSeries lineSeries, ConfigurationContext context) {
        // 根据数据特征优化折线图显示
        ConfigurationContext.DataStatistics stats = context.getDataStatistics();
        
        // 判断是否应该平滑曲线
        if (lineSeries.getSmooth() == null) {
            boolean shouldSmooth = false;
            
            // 数据点较少时平滑显示
            if (stats.getDataPointCount() < 10) {
                shouldSmooth = true;
            }
            
            // 如果数据有明显趋势，使用平滑曲线更好地展示趋势
            Object trendStatsObj = context.getInfo("trendStats");
            if (trendStatsObj instanceof java.util.Map) {
                @SuppressWarnings("unchecked")
                java.util.Map<String, Object> trendStats = (java.util.Map<String, Object>) trendStatsObj;
                if (trendStats.containsValue("increasing") || trendStats.containsValue("decreasing")) {
                    shouldSmooth = true;
                }
            }
            
            // 设置平滑属性
            // 注意：当前的SeriesModel接口没有setSmooth方法，这里仅为示例
            // model.setSmooth(shouldSmooth);
        }
        
        // 判断是否应该显示标记点
        if (lineSeries.getShowSymbol() == null) {
            boolean showSymbol = true;
            
            // 数据点过多时不显示标记点
            if (stats.getDataPointCount() > 30) {
                showSymbol = false;
            }
            
            // 设置标记点显示属性
            // 注意：当前的SeriesModel接口没有setShowSymbol方法，这里仅为示例
            // model.setShowSymbol(showSymbol);
        }
    }
    
    /**
     * 优化折线样式
     * 
     * @param model 系列模型
     * @param context 配置上下文
     */
    private void optimizeLineStyle(SeriesModel model, ConfigurationContext context) {
        // 检查数据密度
        Object densityStatsObj = context.getInfo("densityStats");
        if (densityStatsObj instanceof java.util.Map) {
            @SuppressWarnings("unchecked")
            java.util.Map<String, Object> densityStats = (java.util.Map<String, Object>) densityStatsObj;
            
            // 高密度数据调整
            if (Boolean.TRUE.equals(densityStats.get("isHighDensity"))) {
                // 对于高密度数据，建议使用更细的线条，不显示标记点
                // model.setLineWidth(1);
                // model.setShowSymbol(false);
            }
        }
        
        // 检查是否有异常值
        Object outlierStatsObj = context.getInfo("outlierStats");
        if (outlierStatsObj instanceof java.util.Map) {
            @SuppressWarnings("unchecked")
            java.util.Map<String, Object> outlierStats = (java.util.Map<String, Object>) outlierStatsObj;
            
            if (Boolean.TRUE.equals(outlierStats.get("hasOutliers"))) {
                // 如果有异常值，建议使用标记点标注
                // model.setMarkPoint(true);
            }
        }
    }
    
    @Override
    public DataRangeOptimization getDataRangeOptimization(SeriesModel seriesModel, ConfigurationContext context) {
        DataRangeOptimization optimization = super.getDataRangeOptimization(seriesModel, context);
        
        // 折线图特有的数据范围优化
        // 折线图通常不需要从0开始
        optimization.setStartWithZero(false);
        
        // 折线图适合更紧凑的数据范围，以便更清晰地显示趋势
        optimization.setExpandPercentage(0.05);
        
        return optimization;
    }
}
